const express = require('express');
const router = express.Router();
const { exec } = require('child_process');
const util = require('util');
const fs = require('fs').promises;
const path = require('path');
const { verifyAdmin } = require('../middleware/auth');

const execPromise = util.promisify(exec);

/**
 * @route   GET /api/task/crontab
 * @desc    获取当前用户的Crontab配置
 * @access  私有
 */
router.get('/crontab', async (req, res) => {
  try {
    // 获取当前用户的crontab
    let cronEntries = [];
    
    try {
      const { stdout } = await execPromise('crontab -l');
      
      // 解析crontab输出
      cronEntries = stdout
        .split('\n')
        .filter(line => line.trim() && !line.startsWith('#'))
        .map(line => {
          // 尝试解析crontab行
          const parts = line.trim().split(/\s+/);
          
          if (parts.length >= 6) {
            const schedule = parts.slice(0, 5).join(' ');
            const command = parts.slice(5).join(' ');
            
            return {
              schedule,
              command,
              raw: line
            };
          }
          
          return { raw: line };
        });
    } catch (error) {
      // 用户可能没有crontab
      if (!error.stderr?.includes('no crontab')) {
        throw error;
      }
    }
    
    res.json(cronEntries);
  } catch (error) {
    res.status(500).json({ error: `获取Crontab失败: ${error.message}` });
  }
});

/**
 * @route   POST /api/task/crontab
 * @desc    添加Crontab任务
 * @access  私有 (仅管理员)
 */
router.post('/crontab', verifyAdmin, async (req, res) => {
  try {
    const { schedule, command } = req.body;
    
    if (!schedule || !command) {
      return res.status(400).json({ error: '未提供调度表达式或命令' });
    }
    
    // 验证cron表达式格式
    const cronParts = schedule.split(/\s+/);
    if (cronParts.length !== 5) {
      return res.status(400).json({ error: '无效的Cron表达式格式，应该有5个部分' });
    }
    
    // 获取当前crontab
    let currentCrontab = '';
    try {
      const { stdout } = await execPromise('crontab -l');
      currentCrontab = stdout;
    } catch (error) {
      // 用户可能没有crontab
      if (!error.stderr?.includes('no crontab')) {
        throw error;
      }
    }
    
    // 添加新任务
    const newEntry = `${schedule} ${command}`;
    const updatedCrontab = currentCrontab ? `${currentCrontab}\n${newEntry}` : newEntry;
    
    // 写入临时文件
    const tempFile = `/tmp/crontab-${Date.now()}.txt`;
    await fs.writeFile(tempFile, updatedCrontab);
    
    // 安装新的crontab
    await execPromise(`crontab ${tempFile}`);
    
    // 清理临时文件
    await fs.unlink(tempFile);
    
    res.json({ message: '定时任务已添加' });
  } catch (error) {
    res.status(500).json({ error: `添加Crontab任务失败: ${error.message}` });
  }
});

/**
 * @route   DELETE /api/task/crontab
 * @desc    删除Crontab任务
 * @access  私有 (仅管理员)
 */
router.delete('/crontab', verifyAdmin, async (req, res) => {
  try {
    const { entry } = req.body;
    
    if (!entry) {
      return res.status(400).json({ error: '未提供要删除的任务' });
    }
    
    // 获取当前crontab
    let currentCrontab = '';
    try {
      const { stdout } = await execPromise('crontab -l');
      currentCrontab = stdout;
    } catch (error) {
      // 用户可能没有crontab
      if (error.stderr?.includes('no crontab')) {
        return res.status(404).json({ error: '没有找到Crontab配置' });
      }
      throw error;
    }
    
    // 删除指定任务
    const entries = currentCrontab.split('\n').filter(line => line.trim());
    const updatedEntries = entries.filter(line => line !== entry);
    
    if (entries.length === updatedEntries.length) {
      return res.status(404).json({ error: '未找到指定的任务' });
    }
    
    const updatedCrontab = updatedEntries.join('\n');
    
    // 写入临时文件
    const tempFile = `/tmp/crontab-${Date.now()}.txt`;
    
    if (updatedCrontab) {
      await fs.writeFile(tempFile, updatedCrontab);
      // 安装新的crontab
      await execPromise(`crontab ${tempFile}`);
    } else {
      // 如果没有任务了，清空crontab
      await execPromise('crontab -r');
    }
    
    // 清理临时文件
    if (updatedCrontab) {
      await fs.unlink(tempFile);
    }
    
    res.json({ message: '定时任务已删除' });
  } catch (error) {
    res.status(500).json({ error: `删除Crontab任务失败: ${error.message}` });
  }
});

/**
 * @route   GET /api/task/systemd
 * @desc    获取用户级Systemd定时器列表
 * @access  私有
 */
router.get('/systemd', async (req, res) => {
  try {
    // 检查用户级目录是否存在
    const systemdUserDir = path.join(process.env.HOME || '/root', '.config/systemd/user');
    
    let timers = [];
    
    try {
      await fs.access(systemdUserDir);
      
      // 获取定时器列表
      const { stdout } = await execPromise('systemctl --user list-timers --all');
      
      // 解析输出
      const lines = stdout.split('\n').filter(line => !line.startsWith('NEXT') && !line.includes('timers listed') && line.trim());
      
      timers = lines.map(line => {
        const parts = line.trim().split(/\s+/);
        if (parts.length >= 5) {
          const timerName = parts[4];
          
          return {
            next: `${parts[0]} ${parts[1]}`,
            last: parts[2] !== 'n/a' ? `${parts[2]} ${parts[3]}` : 'n/a',
            name: timerName,
            unit: parts[5],
            active: true
          };
        }
        return null;
      }).filter(Boolean);
      
      // 对于每个定时器，获取详细信息
      for (const timer of timers) {
        const timerName = timer.name;
        try {
          // 获取定时器配置
          const { stdout: timerConfig } = await execPromise(`systemctl --user cat ${timerName}`);
          
          // 提取定时器配置信息
          const onCalendarMatch = timerConfig.match(/OnCalendar=([^\n]+)/);
          timer.schedule = onCalendarMatch ? onCalendarMatch[1] : '';
          
          const unitMatch = timerConfig.match(/Unit=([^\n]+)/);
          timer.serviceUnit = unitMatch ? unitMatch[1] : '';
          
          // 获取服务配置
          if (timer.serviceUnit) {
            try {
              const { stdout: serviceConfig } = await execPromise(`systemctl --user cat ${timer.serviceUnit}`);
              
              // 提取服务配置信息
              const execStartMatch = serviceConfig.match(/ExecStart=([^\n]+)/);
              timer.command = execStartMatch ? execStartMatch[1] : '';
              
              const descriptionMatch = serviceConfig.match(/Description=([^\n]+)/);
              timer.description = descriptionMatch ? descriptionMatch[1] : '';
            } catch (error) {
              // 忽略获取服务配置的错误
            }
          }
        } catch (error) {
          // 忽略获取定时器配置的错误
        }
      }
    } catch (error) {
      // 用户可能没有systemd用户目录
    }
    
    res.json(timers);
  } catch (error) {
    res.status(500).json({ error: `获取Systemd定时器失败: ${error.message}` });
  }
});

/**
 * @route   POST /api/task/systemd
 * @desc    创建Systemd定时器
 * @access  私有 (仅管理员)
 */
router.post('/systemd', verifyAdmin, async (req, res) => {
  try {
    const { name, schedule, command, description = '' } = req.body;
    
    if (!name || !schedule || !command) {
      return res.status(400).json({ error: '未提供名称、调度表达式或命令' });
    }
    
    // 验证名称格式
    if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
      return res.status(400).json({ error: '无效的名称格式' });
    }
    
    // 确保用户级systemd目录存在
    const systemdUserDir = path.join(process.env.HOME || '/root', '.config/systemd/user');
    await fs.mkdir(systemdUserDir, { recursive: true });
    
    // 创建服务单元文件
    const serviceContent = `[Unit]
Description=${description || `Task for ${name}`}

[Service]
Type=oneshot
ExecStart=${command}

[Install]
WantedBy=default.target`;

    // 创建定时器单元文件
    const timerContent = `[Unit]
Description=${description || `Timer for ${name}`}

[Timer]
OnCalendar=${schedule}
Persistent=true

[Install]
WantedBy=timers.target`;

    // 写入文件
    const serviceFile = path.join(systemdUserDir, `${name}.service`);
    const timerFile = path.join(systemdUserDir, `${name}.timer`);
    
    await fs.writeFile(serviceFile, serviceContent);
    await fs.writeFile(timerFile, timerContent);
    
    // 重新加载systemd用户配置
    await execPromise('systemctl --user daemon-reload');
    
    // 启用并启动定时器
    await execPromise(`systemctl --user enable ${name}.timer`);
    await execPromise(`systemctl --user start ${name}.timer`);
    
    res.json({
      message: '定时器已创建并启动',
      name: `${name}.timer`
    });
  } catch (error) {
    res.status(500).json({ error: `创建Systemd定时器失败: ${error.message}` });
  }
});

/**
 * @route   DELETE /api/task/systemd/:name
 * @desc    删除Systemd定时器
 * @access  私有 (仅管理员)
 */
router.delete('/systemd/:name', verifyAdmin, async (req, res) => {
  try {
    const { name } = req.params;
    
    if (!name) {
      return res.status(400).json({ error: '未提供定时器名称' });
    }
    
    // 验证名称格式
    if (!/^[a-zA-Z0-9_-]+\.timer$/.test(name)) {
      return res.status(400).json({ error: '无效的定时器名称格式' });
    }
    
    // 获取不带扩展名的名称
    const baseName = name.replace('.timer', '');
    
    // 停止并禁用定时器
    try {
      await execPromise(`systemctl --user stop ${name}`);
      await execPromise(`systemctl --user disable ${name}`);
    } catch (error) {
      // 定时器可能已经不存在
    }
    
    // 删除单元文件
    const systemdUserDir = path.join(process.env.HOME || '/root', '.config/systemd/user');
    const timerFile = path.join(systemdUserDir, name);
    const serviceFile = path.join(systemdUserDir, `${baseName}.service`);
    
    try {
      await fs.unlink(timerFile);
    } catch (error) {
      // 文件可能不存在
    }
    
    try {
      await fs.unlink(serviceFile);
    } catch (error) {
      // 文件可能不存在
    }
    
    // 重新加载systemd用户配置
    await execPromise('systemctl --user daemon-reload');
    
    res.json({ message: '定时器已删除' });
  } catch (error) {
    res.status(500).json({ error: `删除Systemd定时器失败: ${error.message}` });
  }
});

/**
 * @route   POST /api/task/systemd/:name/toggle
 * @desc    启用或禁用Systemd定时器
 * @access  私有 (仅管理员)
 */
router.post('/systemd/:name/toggle', verifyAdmin, async (req, res) => {
  try {
    const { name } = req.params;
    const { enable } = req.body;
    
    if (!name) {
      return res.status(400).json({ error: '未提供定时器名称' });
    }
    
    if (enable === undefined) {
      return res.status(400).json({ error: '未指定启用或禁用' });
    }
    
    // 验证名称格式
    if (!/^[a-zA-Z0-9_-]+\.timer$/.test(name)) {
      return res.status(400).json({ error: '无效的定时器名称格式' });
    }
    
    if (enable) {
      // 启用并启动定时器
      await execPromise(`systemctl --user enable ${name}`);
      await execPromise(`systemctl --user start ${name}`);
    } else {
      // 停止并禁用定时器
      await execPromise(`systemctl --user stop ${name}`);
      await execPromise(`systemctl --user disable ${name}`);
    }
    
    res.json({
      message: `定时器已${enable ? '启用' : '禁用'}`
    });
  } catch (error) {
    res.status(500).json({ error: `${enable ? '启用' : '禁用'}定时器失败: ${error.message}` });
  }
});

/**
 * @route   GET /api/task/schedules
 * @desc    获取预设定时任务调度表达式
 * @access  私有
 */
router.get('/schedules', async (req, res) => {
  // 预设的cron表达式
  const cronSchedules = [
    { label: '每分钟', value: '* * * * *', description: '每分钟执行一次' },
    { label: '每小时', value: '0 * * * *', description: '每小时整点执行' },
    { label: '每天午夜', value: '0 0 * * *', description: '每天午夜12点执行' },
    { label: '每天凌晨3点', value: '0 3 * * *', description: '每天凌晨3点执行' },
    { label: '每周一早上8点', value: '0 8 * * 1', description: '每周一早上8点执行' },
    { label: '每月1号早上6点', value: '0 6 1 * *', description: '每月1号早上6点执行' },
    { label: '工作日每小时', value: '0 * * * 1-5', description: '周一至周五每小时执行' },
    { label: '每15分钟', value: '*/15 * * * *', description: '每15分钟执行一次' },
    { label: '每天晚上10点', value: '0 22 * * *', description: '每天晚上10点执行' }
  ];
  
  // 预设的systemd计时器表达式
  const systemdSchedules = [
    { label: '每分钟', value: '*:0/1', description: '每分钟执行一次' },
    { label: '每小时', value: 'hourly', description: '每小时执行一次' },
    { label: '每天', value: 'daily', description: '每天执行一次' },
    { label: '每周', value: 'weekly', description: '每周执行一次' },
    { label: '每月', value: 'monthly', description: '每月执行一次' },
    { label: '每天午夜', value: '00:00', description: '每天午夜12点执行' },
    { label: '每天凌晨3点', value: '03:00', description: '每天凌晨3点执行' },
    { label: '每天晚上10点', value: '22:00', description: '每天晚上10点执行' },
    { label: '每周一早上8点', value: 'Mon 08:00', description: '每周一早上8点执行' },
    { label: '每月1号早上6点', value: '*-*-01 06:00', description: '每月1号早上6点执行' }
  ];
  
  res.json({
    cron: cronSchedules,
    systemd: systemdSchedules
  });
});

module.exports = router; 